package core

import (
	"apidoc2entity/export"
	"apidoc2entity/generator"
	"apidoc2entity/model"
	"apidoc2entity/pump"
	"apidoc2entity/transform"
	"fmt"
	"sync"
)

func MySql2Entities(in, out, lang string) error {
	fs := pump.NewPumpOfMysql().PickerPump()
	mCh := transform.MapToStruct(fs)
	g1 := &generator.Generator{Strategy: ChooseStrategy("GO"), OutPath: "./output"}
	g2 := &generator.Generator{Strategy: ChooseStrategy("CS"), OutPath: "./output"}
	out1 := export.Export(g1.Generate(mCh))
	out2 := export.Export(g2.Generate(mCh))
	for s := range Merge(out1, out2) {
		println(s)
	}
	return nil
}

func Excel2Entities(in, out, lang string) error {
	fs := pump.NewPumpOfExcel().PickerPump()
	mCh := transform.MapToStruct(fs)
	g1 := &generator.Generator{Strategy: ChooseStrategy("GO"), OutPath: "./output"}
	g2 := &generator.Generator{Strategy: ChooseStrategy("CS"), OutPath: "./output"}
	out1 := export.Export(g1.Generate(mCh))
	out2 := export.Export(g2.Generate(mCh))
	for s := range Merge(out1, out2) {
		println(s)
	}
	return nil
}

// 选择语言策略
func ChooseStrategy(lang string) generator.IStrategy {
	switch lang {
	case "GO":
		return &generator.GolangStrategy{}
	default:
		return &generator.CSharpStrategy{}
	}
}

// 输出结果合成器
func Merge(chs ...<-chan *model.Product) <-chan string {
	out := make(chan string)
	var wg sync.WaitGroup
	collect := func(in <-chan *model.Product) {
		defer wg.Done()
		for n := range in {
			out <- fmt.Sprintf("%s has built successfully", n.FileName)
		}
	}
	wg.Add(len(chs))
	// FAN-IN
	for _, c := range chs {
		go collect(c)
	}
	// 正确方式
	go func() {
		wg.Wait()
		close(out)
	}()
	return out
}
